﻿namespace DIContainerProvider
{
    #region N A M E S P A C E   I M P O R T S

    using System;
    using CacheProviderInterfaces;
    using Castle.Core.Resource;
    using Castle.MicroKernel.Registration;
    using Castle.Windsor;
    using Castle.Windsor.Configuration.Interpreters;
    using Castle.Windsor.Installer;

    #endregion

    public class WindsorContainerProvider : IDependencyInjectionContainer
    {
        private IWindsorContainer _windsorContainer;

        public WindsorContainerProvider(string configurationPath)
        {
            //Initializing The Container With The Interpreted Xml File.
            this.InitializeWindsorContainer(configurationPath);
        }


        #region IIOCProvider Members

        public T Resolve<T>()
        {
            return this._windsorContainer.Resolve<T>();
        }

        public T Resolve<T>(System.Collections.IDictionary arguments)
        {
            return this._windsorContainer.Resolve<T>(arguments);
        }

        public T Resolve<T>(object argumentsAsAnonymousType)
        {
            return this._windsorContainer.Resolve<T>(argumentsAsAnonymousType);
        }

        public T Resolve<T>(string key)
        {
            return this._windsorContainer.Resolve<T>(key);
        }

        public object Resolve(Type service)
        {
            return this._windsorContainer.Resolve(service);
        }

        public T Resolve<T>(string key, System.Collections.IDictionary arguments)
        {
            return this._windsorContainer.Resolve<T>(key, arguments);
        }

        public object Resolve(string key, System.Collections.IDictionary arguments)
        {
            return this._windsorContainer.Resolve(key, arguments);
        }

        public T Resolve<T>(string key, object argumentsAsAnonymousType)
        {
            return this._windsorContainer.Resolve<T>(key, argumentsAsAnonymousType);
        }

        public void InitializeWindsorContainer(string configurationPath)
        {
            IResource resource;
            if (configurationPath.StartsWith("assembly://", StringComparison.InvariantCultureIgnoreCase))
                resource = new AssemblyResource(configurationPath);
            else
                //Path Of the Windsor Dependency XML Configuration File
                resource = new FileResource(configurationPath);

            XmlInterpreter xmlInterpreter = new XmlInterpreter(resource);

            //if (this._windsorContainer != null)
            //    this._windsorContainer.Install(Configuration.FromXml(resource));
            ////this._windsorContainer = new WindsorContainer(this._windsorContainer, xmlInterpreter);
            //else
            //    this._windsorContainer = new WindsorContainer(xmlInterpreter);

            if (this._windsorContainer == null)
                this._windsorContainer = new WindsorContainer();

            this._windsorContainer.Install(Configuration.FromXml(resource));
        }

        public void RegisterType(Type type, object instance)
        {
            this._windsorContainer.Register(Component.For(type).Instance(instance));
        }

        #endregion
    }
}
